<template>
  <div>
    <div class="img-content"
          v-loading="imgLoading"
          element-loading-text="Loading, please wait..."
          :style="{width: configKonva.width + 'px', height: configKonva.height + 'px'}"
        >
      <v-stage 
        :config="configKonva"
        @mousedown="handleStageMouseDown"
        @click="stageClick"
      >
          <v-layer ref="bgImg" @mousemove="bgImgMouseover">
              <v-image :config="imageConfig"/>
          </v-layer>

          <v-layer>
              <v-group :config="dotGroupConfig"
                  @dragmove="(e) => {groupDragmove(e)}"
                  @mouseover="(e) => {groupMouseover(e)}"
                  @mouseout="(e) => {groupMouseout(e)}">
                  <v-arrow :config="arrowConfig"></v-arrow>
                  <v-circle :config="configCircle" 
                  @transform="(e) => {circleTransform(e)}"></v-circle>
                  <v-text :config="textConfig"></v-text>
              </v-group>
              <v-transformer ref="transformer" :config="transformerConfig" />
          </v-layer>
      </v-stage>
    </div>
    <div slot="footer" class="dialog-footer">
      <div class="dot-position-info">
        <div>Position:<span>{{position.x}}, {{position.y}}</span></div>
        <div>Rotation:<span>{{position.rotation}}°</span></div>
      </div>
    </div>
  </div>
  
 
</template>

<script>
import { generateRenderMap, pixelHitTest } from '../../middleware/tools.js'
export default{   
    data(){return{
    configKonva: {
       width: 600,
       height: 500,
    },
    imgLoading: true,
    prevMousePos: {}, //先前的点位
    isFirstSetDotPoint: true,
    position: {
      x: 0,
      y: 0,
      rotation: 0,
    },
    imageConfig: {
      name: 'bg-img',
      image: '',
    },
    textConfig: {
          text: "Test Data",
          fontSize: 14,
          fontFamily: 'Calibri',
          fill: "rgba(255, 255, 0, 1.0)",
          visible: false,
          shadowColor: 'black',
          shadowBlur: 6,
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          shadowOpacity: 1,
          cornerRadius: 6
        },
    transformerConfig: {
        resizeEnabled: false  //是否允许大小重新设置
      },
    dotGroupConfig: {
            name: `dot-group`,
            x: 200 ,
            y: 100 ,
            draggable: true,
            disabled: false,
            dragBoundFunc: (pos) => {
              var newY = pos.y < this.configKonva.height ? (pos.y > 0 ? pos.y : 0) : this.configKonva.height;
              var newX = pos.x < this.configKonva.width ? (pos.x > 0 ? pos.x : 0) : this.configKonva.width;
              return {
                x: newX,
                y: newY
              };
            }
          },
    configCircle: {
      name: `circle`,
            // x: 200,
            // y: 100,
            radius: 8,
            fill: "rgba(225, 55, 55, 1)",
            stroke: "rgba(255, 255, 0, 1.0)",
            strokeWidth: 2,
            rotation: 0,
            disabled: true,
            shadowColor: 'black',
            shadowBlur: 8,
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            shadowOpacity: 0.8,
            cornerRadius: 6
    },
    arrowConfig: {
            name: `arrow`,
            fill: "rgba(225, 55, 55, 1)",
            // x: 200,
            // y: 100,
            points:[0, 0, 0, 0, 30, 0],
            rotation:  -90,
            stroke:"rgba(182, 182, 182, 1.0)" ,
            strokeWidth: 2,
            disabled: false,
            shadowColor: 'black',
            shadowBlur: 8,
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            shadowOpacity: 0.8,
            cornerRadius: 6
          }
  }},
  mounted() {
    this.creatImg("your image url");
  },
  methods: {
    // 渲染底图
    creatImg (src) {
      const image = new Image();
      image.crossOrigin = 'Anonymous';
      image.src = src;
      image.src = require('./pic/BlackForestNight_floorplan.jpg');
      image.onload = (e) => {
        const {width, height} = image;
        if (width <= 600) {
          image.width = 600;
        } else if (width > 800) {
          image.width = 800;
        } else {
          image.width = width;
        }
        image.height = image.width * (height / width);

        this.configKonva.height = image.height;
        this.configKonva.width = image.width;
        this.imageConfig.image = image;


        // 图片加载完成后 计算 需要检测的像素点
        const _this = this;
        setTimeout(function(){
          const bgImgNode = _this.$refs.bgImg.getNode();
          _this.maskPixelData = generateRenderMap(
            image.width, image.height, bgImgNode.getContext(), 7
          );
          _this.imgLoading = false;
          console.log(_this.maskPixelData );
        }, 1000 )

      };
    },
    stageClick(e) {
      console.log("stage recive click");
      const targetNodeName = e.target.name();
      if (targetNodeName === 'bg-img' && this.isFirstSetDotPoint && this.bgImgAllowed) {
        const pos = e.target.getStage().getPointerPosition();
        this.dotGroupConfig.x
          = this.position.x = Math.round(pos.x);
        this.dotGroupConfig.y
          = this.position.y = Math.round(pos.y);
        this.arrowConfig.rotation = -90;
        this.isFirstSetDotPoint = false;
      }
    },
     formatRotation(r = 0) {
      if (r < 0) {
        return Math.round( 360 + r );
      } else if (r > 180) {
        return Math.round( r - 360 );
      } else {
        return Math.round( r ); //default value
      }
    },
    
    // 鼠标按下事件
    handleStageMouseDown(e) {
      if ( !e.target.attrs.disabled && (e.target.name().includes('circle') || e.target.name().includes('arrow'))) {   // 点击的是可移动的dot
        this.updateTransformer('circle');
      } else if (e.target.getParent() && e.target.getParent().className === 'Transformer') {  // 点击的是Transformer

      } else {
        this.updateTransformer('');  //如果点击其他目标清除旋转框
      }
    },
    // 鼠标悬浮在红点图标上时候的响应
    groupMouseover(e) {
      const textWidth = e.target.getParent().findOne('Text').width();
      const textHeight = e.target.getParent().findOne('Text').height();
      this.textConfig.offset = {
        x: textWidth / 2,
        y: -textHeight
      }
      this.textConfig.visible = true;

      this.stage = e.target.getStage();
      this.stage.container().style.cursor = e.target.attrs.disabled ? 'auto' : 'move';
    },

    // 鼠标离开红点图标后的响应
    groupMouseout(e) {
      this.textConfig.visible = false;
      const stage = e.target.getStage();
      stage.container().style.cursor = 'auto';
    },
    // dot 拖动 获取其x y值
    groupDragmove(e) {;
      console.log("group drag move")
      this.position.x = Math.round( e.target.x() );
      this.position.y = Math.round( e.target.y() );
      const isProhibitedAreas = pixelHitTest(this.maskPixelData, {x: this.position.x, y: this.position.y});
      if (isProhibitedAreas) {//如果是禁入区把值修改成之前的位置数据，并将鼠标变成不可拖入
        e.target.x(this.prevMousePos.x);
        e.target.y(this.prevMousePos.y);
        this.stage.container().style.cursor = 'not-allowed';
      } else {
        this.prevMousePos = {x: this.position.x, y: this.position.y};//更新鼠标位置数据
        this.stage.container().style.cursor = 'move';
      }
    },
    
    updateTransformer(nodeName) {
      const transformerNode = this.$refs.transformer.getNode();
      const stage = transformerNode.getStage();
      const selectedNode = stage.findOne('.' + nodeName);
      if (selectedNode === transformerNode.node()) {
        return;
      }

      if (selectedNode) {
        transformerNode.nodes([selectedNode]);
      } else {
        transformerNode.nodes([]);
      }
    },

    // dot 旋转 获取其 r值
    circleTransform(e) { 
      const r = e.target.rotation();
      this.arrowConfig.rotation =  r - 90;
      this.position.rotation = this.formatRotation(r);
    },

    formatRotation(r = 0) {
      r = Number(r);
      if (r < 0) {
        return Math.round( 360 + r );
      } else if (r > 180) {
        return Math.round( r - 360 );
      } else {
        return Math.round( r );
      }
    },

    // 检测图片上鼠标移动事件
    bgImgMouseover(e) {
      console.log("bg img mouseover")
      if (!this.stage) {
        this.stage = e.target.getStage();
      }
      const isProhibitedAreas = pixelHitTest(this.maskPixelData, {x: e.evt.layerX, y: e.evt.layerY});
      if (isProhibitedAreas) {
        this.stage.container().style.cursor = 'not-allowed';
        this.bgImgAllowed = false;
      } else {
        this.stage.container().style.cursor = 'auto';
        this.bgImgAllowed = true;
      }
    },

  }
};
</script>
<style lang="less" scoped>
.dialog-footer{
    display: flex;
    justify-content: flex-end;
    padding: 10px;
    position: relative;
    align-items: center;
  }
</style>
